#pragma once 
#include <functional>
#include <iostream>
#include <pthread.h>
#include "Log.hpp"
using namespace LogModule;
namespace ThreadModule {
    static uint32_t number = 1;
    class Thread {
        using func_t = std::function<void()>;
        private:
            void EnableDetach() {
                _isdetach = true;
            }
            void EnableRunning() {
                _isrunning = true;
            }
            static void* routine(void* args) { // 这里使用静态就是为了消除自身this指针的影响
                Thread* temp = static_cast<Thread*>(args);
                temp->EnableRunning();
                if(temp->_isdetach) {
                    temp->Detach();
                }
                pthread_setname_np(temp->_tid, temp->_name.c_str());
                temp->_func();
                return nullptr;
            }
        public:
            Thread(func_t func)
            :_tid(0),
            _isdetach(false),
            _isrunning(false),
            _res(nullptr),
            _func(func) {

            }
            void Detach() {
                if(_isdetach) {
                    return;
                }
                if(_isrunning) {
                    pthread_detach(_tid);
                }
                EnableDetach();
                return;
            }
            std::string Name() {
                return _name;
            }
            bool Start() {
                if(_isrunning) {
                    return false;
                }
                int n = pthread_create(&_tid, nullptr, routine, this);
                if(n != 0) {
                    return false;
                }else {
                    return true;
                }
            }
            bool Stop() {
                if(!_isrunning) {
                    return false;
                }else {
                    int n = pthread_cancel(_tid);
                    if(n != 0) {
                        return false;
                    }else {
                        _isrunning = false;
                        return true;
                    }
                }
            }
            void Join() {
                if(_isdetach) {
                    return;
                }else {
                    int n = pthread_join(_tid, &_res);
                    if(n != 0) {
                        LOG(LogLevel::DEBUG) << "Join线程失败";
                    }else {
                        LOG(LogLevel::DEBUG) << "Join线程成功";
                    }
                }
            }
            ~Thread() {}
        private:
            pthread_t _tid;
            std::string _name;
            bool _isdetach;
            bool _isrunning;
            void* _res;
            func_t _func;
    };
}